У цій лабораторній роботі ми аналізуємо сервіс онлайн таксі.
#install.packages("RSQLite")
#install.packages("lubridate")
#install.packages("dplyr")
#install.packages("jsonlite")
#install.packages("purrr")
#install.packages("tidyr")
#install.packages("ggplot2")
#install.packages("plotly")
library(RSQLite)
library(lubridate)
library(dplyr)
library(jsonlite)
library(purrr)
library(tidyr)
library(ggplot2)
library(plotly)data <- orders %>%
mutate(
from_place = map_chr(where_from, ~ fromJSON(.)$place),
to_place = map_chr(where_to, ~ ifelse(is.na(.) | . == "", "По городу", fromJSON(.)$place))
)
# Топ популярних місць відправлення
top_places_from <- data %>%
group_by(from_place, to_place) %>%
summarise(count = n()) %>%
arrange(desc(count)) %>%
head(10)
# Виводимо топ-10 популярних місць відправлення
top_places_from %>%
kable()| from_place | to_place | count |
|---|---|---|
| улица Некрасова, 27 | По городу | 273 |
| улица Киселёва, 12 | По городу | 218 |
| улица Киселёва, 12, Минск | По городу | 193 |
| проспект Победителей, 65, Минск | По городу | 186 |
| проспект Машерова, 11 | По городу | 180 |
| проспект Победителей, 65 | По городу | 158 |
| Гвардейская улица, 16, Минск | По городу | 147 |
| улица Янки Купалы, 25 | По городу | 147 |
| Сторожовская улица, 8 | По городу | 146 |
| улица Академика Карского, 4, Минск | По городу | 140 |
# Розраховуємо тривалість поїздки (у хвилинах) та фільтруємо за розумним порогом
data <- orders %>%
mutate(
start_time = as.POSIXct(finish_pickup_date, origin = "1970-01-01"),
end_time = as.POSIXct(finish_date),
# Обчислення тривалості поїздки у хвилинах
duration = as.numeric(difftime(end_time, start_time, units = "mins"))
)
# Топ-10 найдовших поїздок
top_durations <- data %>%
arrange(desc(duration)) %>%
head(10)
# Виводимо топ-10 найдовших поїздок
top_durations %>% select(id, start_time, end_time, duration)## id start_time end_time duration
## 1 2488272 2019-06-01 03:57:56 2019-06-09 06:47:02 11689.100
## 2 2487777 2019-06-01 01:16:18 2019-06-07 11:04:02 9227.733
## 3 2990956 2019-12-24 00:22:30 2019-12-28 21:30:54 7028.400
## 4 2548961 2019-06-23 01:55:44 2019-06-27 11:20:16 6324.533
## 5 2541110 2019-06-20 20:56:32 2019-06-24 18:14:18 5597.767
## 6 2524194 2019-06-14 19:38:06 2019-06-18 11:11:49 5253.717
## 7 2568379 2019-06-29 07:37:20 2019-07-02 05:45:07 4207.783
## 8 2349687 2019-04-05 18:14:12 2019-04-08 14:46:22 4112.167
## 9 2335834 2019-03-29 17:53:22 2019-04-01 12:57:26 3964.067
## 10 3009859 2019-12-28 13:10:01 2019-12-30 10:54:59 2744.967
# Відсікаємо аномальні значення
data <- data %>%
filter(duration > 0 & duration <= 300)
# Середня тривалість поїздок за часом доби
time_of_day_analysis <- data %>%
mutate(
time_of_day = case_when(
hour(start_time) >= 5 & hour(start_time) < 12 ~ "Утро",
hour(start_time) >= 12 & hour(start_time) < 17 ~ "День",
hour(start_time) >= 17 & hour(start_time) < 21 ~ "Вечер",
TRUE ~ "Ночь"
)
) %>%
group_by(time_of_day) %>%
summarise(avg_duration = mean(duration, na.rm = TRUE))
# Виведення середнього часу поїздок за часом доби
time_of_day_analysis## # A tibble: 4 × 2
## time_of_day avg_duration
## <chr> <dbl>
## 1 Вечер 20.5
## 2 День 20.6
## 3 Ночь 18.3
## 4 Утро 20.8
# Обробка даних для аналізу за годинами та днями тижня
data <- orders %>%
mutate(
hour = hour(as.POSIXct(create_date, origin = "1970-01-01")),
day = wday(as.POSIXct(create_date, origin = "1970-01-01"), label = TRUE)
) %>%
group_by(day, hour) %>%
summarise(count = mean(n(), na.rm = TRUE)) %>%
ungroup() %>%
pivot_wider(names_from = hour, values_from = count, values_fill = 0) %>%
pivot_longer(cols = -day, names_to = "hour", values_to = "count")
# Перетворення hour у числовий формат
data$hour <- as.numeric(data$hour)
# Побудова графіка
p <- ggplot(data, aes(x = hour, y = count, color = day)) +
geom_line() +
labs(title = "Середня кількість поїздок за днями тижня та годинами",
x = "Година", y = "Середня кількість поїздок") +
theme_minimal()
# Перетворюємо графік ggplot у інтерактивний plotly
ggplotly(p)# Перетворюємо часові мітки у формат datetime
data <- orders %>%
mutate(
create_date = as.POSIXct(create_date),
create_time = as.POSIXct(start_pickup_date),
pickup_time = as.POSIXct(finish_pickup_date),
wait_time = as.numeric(difftime(pickup_time, create_time, units = "mins")),
season = case_when(
month(create_date) %in% c(12, 1, 2) ~ "Зима",
month(create_date) %in% c(3, 4, 5) ~ "Весна",
month(create_date) %in% c(6, 7, 8) ~ "Літо",
TRUE ~ "Осінь"
)
) %>%
filter(wait_time > 0 & wait_time <= 30)
mean_wait <- data %>%
group_by(hour = hour(create_time), season) %>%
summarise(avg_wait_time = mean(wait_time, na.rm = TRUE))
# Графік середнього часу очікування
p <- ggplot(mean_wait, aes(x = factor(hour), y = avg_wait_time, fill = season)) +
geom_bar(stat = "identity", position = "dodge") +
scale_fill_manual(values = c("Зима" = "#1f78b4", "Весна" = "#33a02c", "Літо" = "#e31a1c", "Осінь" = "#ff7f00")) +
labs(title = "Середній час очікування таксі за годинами дня та сезонами",
x = "Години дня",
y = "Середній час очікування (хв)") +
theme_minimal()
# Перетворюємо графік ggplot у інтерактивний plotly
ggplotly(p)# Групуємо дані за замовленнями
orders_data <- orders %>%
mutate(
total_distance = inside_distance + outside_distance,
create_time = as.POSIXct(start_pickup_date),
pickup_time = as.POSIXct(finish_pickup_date),
wait_time = as.numeric(difftime(pickup_time, create_time, units = "mins")),
) %>%
filter(total_distance > 0, total_distance <= 50, wait_time > 0, wait_time <= 30)
# Групування даних
orders_data <- orders_data %>%
group_by(dist_group = cut(total_distance, breaks = seq(0, 50, by = 2)),
time_group = cut(wait_time, breaks = seq(0, 30, by = 2))) %>%
summarise(count = n(),
avg_dist = mean(total_distance, na.rm = TRUE),
avg_wait_time = mean(wait_time, na.rm = TRUE))
ggplot(orders_data, aes(x = avg_dist, y = avg_wait_time)) +
geom_point(aes(size = count), alpha = 1/2) +
geom_smooth() +
scale_size_area() +
labs(
title = "Залежність кількості замовлень від дистанції та часу подачі",
x = "Дистанція (км)",
y = "Час подачі (хв)"
) +
theme_minimal()library(tidyverse)
# Готуємо дані для аналізу популярності тарифів залежно від дистанції
tariffs_data <- orders %>%
mutate(
total_distance = inside_distance + outside_distance
) %>%
filter(rec_tariff > 0, total_distance > 0, total_distance <= 50) %>%
group_by(type_tariff, dist_group = cut(total_distance, breaks = seq(0, 50, by = 1))) %>%
summarise(count = n(), .groups = 'drop') %>%
# Перетворюємо фактори у числовий формат для графіка
mutate(dist_group_num = as.numeric(sub("\\((.+),.+\\]", "\\1", as.character(dist_group))))
head(tariffs_data)## # A tibble: 6 × 4
## type_tariff dist_group count dist_group_num
## <chr> <fct> <int> <dbl>
## 1 Business (0,1] 52 0
## 2 Business (1,2] 406 1
## 3 Business (2,3] 967 2
## 4 Business (3,4] 1110 3
## 5 Business (4,5] 1272 4
## 6 Business (5,6] 1045 5
# Побудова графіка залежності кількості замовлень від дистанції за тарифами
p <- ggplot(tariffs_data, aes(x = dist_group_num, y = count, color = type_tariff)) +
geom_line() +
labs(
title = "Популярність тарифів залежно від дистанції поїздки",
x = "Дистанція (км)",
y = "Кількість замовлень"
) +
theme_minimal()
ggplotly(p)# Фільтрація активних клієнтів
active_clients <- data %>%
filter(trip_count > 1) # наприклад, клієнти з більш ніж 1 поїздкою
# Візуалізація: кількість поїздок на клієнта
p <- ggplot(active_clients, aes(x = trip_count)) +
geom_histogram(binwidth = 0.5, fill = "skyblue", color = "black") +
labs(
title = "Частота поїздок за клієнтами",
x = "Кількість поїздок",
y = "Кількість клієнтів"
) +
theme_minimal()
ggplotly(p)# Візуалізація: зв'язок днів з першої поїздки та кількості поїздок
p <- ggplot(active_clients, aes(x = days_since_first_trip, y = trip_count)) +
geom_point(alpha = 0.5) +
geom_smooth(method = "lm") +
labs(
title = "Кількість поїздок за часом з першої поїздки",
x = "Днів з першої поїздки",
y = "Кількість поїздок"
) +
theme_minimal()
ggplotly(p)